package zero.tech.games.dn.work.sync;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.alibaba.fastjson.JSONObject;

import zero.tech.core.ZeroContext;
import zero.tech.core.data.KeyVal;
import zero.tech.core.util.StringHelper;
import zero.tech.core.work.AynWork;
import zero.tech.core.work.WorkManager;
import zero.tech.games.common.WaterMode;
import zero.tech.games.dn.data.DnBigPanel;
import zero.tech.games.dn.data.DnConfig;
import zero.tech.games.dn.data.DnRoomCache;
import zero.tech.games.dn.data.DnSmallPanel;
import zero.tech.games.dn.data.entity.PlayerBigCal;
import zero.tech.games.dn.data.entity.PlayerSmallCal;
import zero.tech.games.dn.work.queue.AfterGameOverCalculateQueueWork;
import zero.tech.games.entity.games.Club;
import zero.tech.games.logic.common.Room;
import zero.tech.games.logic.data.panel.SmallPanel;
import zero.tech.games.logic.service.api.ILogicService;
import zero.tech.wsnet.controller.LogicController;

public class GameOverCalculateSyncWork extends AynWork{
	private Room room;
	private int source;
	@Override
	public void init(Object... objs) throws Exception {
		room=(Room) objs[0];
		this.source=(int) objs[1];
	}

	@Override
	public void run() {
		synchronized (room.getTransform_lock()) {
			bigCalculate(room);
			Club club=room.getClub();
			if(club!=null) {
				//结算代码在此处
				roomTransform(room);
			}else {
				//结算砖石
				diamondTransform(room);
			}
			WorkManager.getManager().submit(AfterGameOverCalculateQueueWork.class,room,source);
		}
	}
	
	private void diamondTransform(Room room) {
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		int water_mode=dnConfig.getWater_mode();
		long water_num=dnConfig.getWater_num();
		Map<Integer,LogicController> controllers=room.getAllControllers();
		Map<Integer,Long> diamondchangemap=new HashMap<>();
		if(water_mode==WaterMode.AA) {
			for(LogicController logicController:controllers.values()) {
				int uid=logicController.getId();
				diamondchangemap.put(uid, -water_num);
			}
		}
		if(!diamondchangemap.isEmpty()) {
			ILogicService logicService=ZeroContext.getInstance(ILogicService.class);
			logicService.gameUpdateDiamondBatch(room, diamondchangemap);
		}
	}

	private void roomTransform(Room room) {
		DnConfig dnConfig = (DnConfig) room.getGameConfig();
		int water_mode=dnConfig.getWater_mode();
		long water_num=dnConfig.getWater_num();
		long free_water_num=dnConfig.getFree_water_num();
		Map<Integer,Long> watermap=new HashMap<>();
		Map<Integer,Long> goldchangemap=new HashMap<>();
		
		Map<Integer,Long> winmap=new HashMap<>();
		Map<Integer,LogicController> controllers=room.getControllersWithoutAdvance();
		List<Integer> uids=new ArrayList<Integer>();
		for(LogicController logicController:controllers.values()) {
			int uid=logicController.getId();
			long gold_from_gate=logicController.getGold_from_gate();
			long gold=logicController.getGold();
			long win=gold-gold_from_gate;
			winmap.put(uid, win);
			uids.add(uid);
		}
		if(water_mode==WaterMode.WINER) {
			//大赢家抽水
			List<KeyVal<Integer, Long>>  list=StringHelper.parseMapToList(winmap);
			Collections.sort(list,new Comparator<KeyVal<Integer, Long>>() {
				@Override
				public int compare(KeyVal<Integer, Long> o1, KeyVal<Integer, Long> o2) {
					return (int) (o2.getV()-o1.getV());
				}
			});
			int bigwinner_uid=list.get(0).getK();
			long win=list.get(0).getV();
			if(win>free_water_num) {
				//超出面抽水限额,需要进行抽水
				watermap.put(bigwinner_uid, water_num);
			}
		}else {
			//在这里必须是要参与过游戏的才抽水
			
			
			//AA抽水
			for(LogicController logicController:controllers.values()) {
				int uid=logicController.getId();
				watermap.put(uid, water_num);
			}
		}
		//除去抽水
		for(LogicController logicController:controllers.values()) {
			int uid=logicController.getId();
			long gold_from_gate=logicController.getGold_from_gate();
			long gold=logicController.getGold();
			if(watermap.containsKey(uid)) {
				gold=gold-watermap.get(uid);
			}
			logicController.setGold(gold);
			long change=gold-gold_from_gate;
			goldchangemap.put(uid, change);
		}
		
		if(water_mode==WaterMode.WINER) {
			//计算平分业绩
			long total=0;
			for(Entry<Integer,Long> entry:watermap.entrySet()) {
				total+=entry.getValue();
			}
			watermap.clear();
			Map<Integer,LogicController> joiners=room.getControllersWithoutWather();
			long pinjun=total/joiners.size();
			for(LogicController logicController:joiners.values()) {
				watermap.put(logicController.getId(), pinjun);
			}
		}
		
		String joiners=JSONObject.toJSONString(uids);
		ILogicService logicService=ZeroContext.getInstance(ILogicService.class);
		logicService.gameUpdateBatch(room, joiners, null, goldchangemap, watermap);		
	}

	private void bigCalculate(Room room) {
		DnBigPanel dnBigPanel = new DnBigPanel();
		Map<Integer,Integer> lose_times=new HashMap<>();
		Map<Integer,Integer> win_times=new HashMap<>();
		Map<Integer,Integer> total_win_score=new HashMap<>();
		Map<Integer,Long> total_win_gold=new HashMap<>();
		DnRoomCache dnRoomCache = (DnRoomCache) room.getRoomCache();
		for(SmallPanel smallPanel:dnRoomCache.getSmallPanels().values()) {
			DnSmallPanel dnSmallPanel = (DnSmallPanel) smallPanel;
			List<PlayerSmallCal> playerSmallCals=dnSmallPanel.getPlayerCals();
			for(PlayerSmallCal playerSmallCal:playerSmallCals) {
				int uid=playerSmallCal.getSimpleUser().getUid();
				int cur_win_score=playerSmallCal.getCur_win_score();
				long cur_win_gold=playerSmallCal.getCur_win_gold();
				if(cur_win_gold!=0) {
					if(!total_win_gold.containsKey(uid)) {
						total_win_gold.put(uid, cur_win_gold);//当前总输赢
					}else {
						long old=total_win_gold.get(uid);
						total_win_gold.put(uid, old+cur_win_gold);
					}
				}
				if(cur_win_score<0) {
					if(!lose_times.containsKey(uid)) {
						lose_times.put(uid, 1);//输局数+1
					}else {
						int old=lose_times.get(uid);
						lose_times.put(uid, old+1);
					}
				}
				if(cur_win_score>0) {
					if(!win_times.containsKey(uid)) {
						win_times.put(uid, 1);//赢局数+1
					}else {
						int old=win_times.get(uid);
						win_times.put(uid, old+1);
					}
				}
				if(cur_win_score!=0) {
					if(!total_win_score.containsKey(uid)) {
						total_win_score.put(uid, cur_win_score);//赢总分
					}else {
						int old=total_win_score.get(uid);
						total_win_score.put(uid, old+cur_win_score);
					}
				}
				
			}
		}
		
		for(LogicController logicController:room.getAllControllers().values()) {
			int uid=logicController.getId();
			PlayerBigCal playerBigCal=new PlayerBigCal();
			playerBigCal.setSimpleUser(logicController.getSimpleUser());
			playerBigCal.setLose_times(lose_times.get(uid)==null?0:lose_times.get(uid));
			playerBigCal.setWin_times(win_times.get(uid)==null?0:win_times.get(uid));
			playerBigCal.setTotal_win_score(total_win_score.get(uid)==null?0:total_win_score.get(uid));
			playerBigCal.setTotal_win_gold(total_win_gold.get(uid)==null?0:total_win_gold.get(uid));
			playerBigCal.setLeft_gold(logicController.getGold());
			dnBigPanel.getPlayerCals().add(playerBigCal);
		}
		
		
		dnBigPanel.setGameOverTime(System.currentTimeMillis());
		dnRoomCache.setBigPanel(dnBigPanel);
	}

}
